R tiene una inmensa capacidad de graficar y visualizar datos de todo tipo, incluídos datos genéticos.
Las gráficas pueden hacerse desde la base de R (base) o con paquetes especializados en graficar, como ggplot2 y ggbio. También paquetes especializados en un tipo de datos que incluyen funciones para graficar, como ape para árboles filogenéticos.
En esta sección veremos una introducción a graficar en R usando graphics que es el sistema que viene con base y luego con ggplot2.
Una de las mejores formas de aprender a hacer gráficas en R es buscar en internet/libro una gráfica parecida a la que queremos hacer y ver el código. Algunas recomendaciones:
Acordeón de colores para tener a la mano: * R puede trabajar con paletas de colores pre-establecidas, chécalas en este link. * No te pierdas cómo nombrar muchos otros colores y utilizar otras paletas con más colores en la R Color Reference Sheet. * Si necesitas generar muchos colores o colores amigables con la banda daltónica I wanthue es lo que necesitas.
Estas son las principales funciones para graficar utilizando la base de R. Puedes buscar ayuda de cada una con su nombre, y además en explorar argumentos extras con ?par
plot: generic x-y plottingbarplot: bar plotsboxplot: box-and-whisker plothist: histogramspie: pie chartsdotchart: cleveland dot plotsimage, heatmap, contour, persp: functions to generate image-like plotsqqnorm, qqline, qqplot: distribution comparison plotsDando x, y:
largo<-c(10,20,11,15,16,20)
ancho<-c(5,10,7,8,8,11)
plot(x=largo, y=ancho)
Dando un objeto que tiene dos columnas, se toman automático como x,y:
# ver el contenido de `cars`(una df ejemplo que viene con R)
head(cars)
## speed dist
## 1 4 2
## 2 4 10
## 3 7 4
## 4 7 22
## 5 8 16
## 6 9 10
plot(cars)
Si queremos especificar qué columnas serán x, y del objeto:
# graficar vel vs distancia
plot(x=cars$speed, y=cars$dist)
Cambiar título de ejes e íconos:
# graficar vel vs distancia
plot(x=cars$speed, y=cars$dist, xlab="Velocidad", ylab="Distancia", cex=0.5, pch=19)
Ejercicio: mira la ayuda de par y explica qué hacen los argumentos cex y pch.
Ejercicio: Repite la figura anterior pero cambiando los puntos por triángulos azules. Necesitarás esto.
Los histogramas sirven para representar la frecuencia de los valores de datos numéricos. Por ejemplo los datos islands que vienen pre-cargados tienen el nombre y tamaño de las islas del mundo:
head(islands)
## Africa Antarctica Asia Australia Axel Heiberg Baffin
## 11506 5500 16988 2968 16 184
Con un histograma podemos ver que la mayor parte de las islas son pequeñas y que hay unas cuantas grandes:
hist(x=islands)
Con el argumento breaks podemos cambiar la cantidad de rangos en las que dividir el histograma.
hist(x=islands, breaks=5)
Podemos escribir hist(islands) porque islands es un vector. Si tuviéramos los datos en una data.frame entonces hay que especificar de qué columna queremos el histograma:
hist(cars$speed)
Podemos hacer gráficas de barras con base en un vector una dataframe donde tengamos datos con la "altura" de las barras, por ejemplo los datos islands que vienen pre-cargados:
# ver los datos de los primeros 6 elementos de islands
islands[1:6]
## Africa Antarctica Asia Australia Axel Heiberg Baffin
## 11506 5500 16988 2968 16 184
# Hacer un barplot con los primeros elementos de islands.
barplot(islands[1:6], ylab="tamaño")
Las gráficas que hemos visto hasta ahora pueden verse un poco feas de inicio y puede tomar un rato y mucho código arreglarlas a algo hermoso. ggplot2 es un paquete que ahorra este trabajo y que ahora es ampliamente adoptado.
ggplot2 construye gráficas "definiendo sus componentes paso a paso".
Para poder usar ggplot2 se requiere que la data.frame esté en formato largo. Puedes revisar estos apuntes para entender más sobre qué es "el formato largo".
Términos importantes:
Ojo: Mucho mejor que ver la ayuda de cada función es ver el R Graphics Cookbook u otros de los recursos en línea al principio de estas notas
Y para familiarizarte con lo que puede hacer ggplot2 y sus argumentos, imprime y pon bajo la almohada su [acordeón]https://raw.githubusercontent.com/rstudio/cheatsheets/main/data-visualization.pdf)
ggplot la función principal donde se especifican el set de datos y las variables a graficar.
geom_point()geom_bar()geom_line()geom_area()geom_histogram()geom_density()`geom_boxplot()
aes los estéticos que pondremos: forma, transparencia (alpha), color, relleno, tipo de línea, etc.
scales para especificar si los datos se graficarán de forma continua, discreta, logarítmica.
themes para modificar los elementos de la gráfica no relacionados con los datos, como el tipo de letra y el color del fondo.
Una gráfica de ggplot se puede guardar en un objeto de r, e irle sumando a dicho objeto otros elementos, con +.
# Cargar ggplot2
library(ggplot2)
# Examinar datos pre-cargados
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
# graficar
ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width)) + geom_point()
Pregunta: ¿Qué hace el símbolo +? Nota que el código anterior tmb puede escribirse así:
myplot<-ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width))
myplot + geom_point()
Los colores y formas se cambian en aes:
ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width, color= Species, shape=Species)) + geom_point()
Ya sea en el aes de la función inicial o dentro de los geoms (Nota que el tamaño no es un aes, sino un argumento de geom_point)
ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width)) +
geom_point(aes(color= Species, shape=Species), size=3)
Si queremos quitar el fondo gris:
ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width)) +
geom_point(aes(color= Species, shape=Species), size=3) +
theme_bw()
Aveces queremos graficar en páneles separados la misma info para diferentes tratamientos o especies. Por ejemplo:
ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width)) +
geom_point() +
facet_grid(Species ~ .)
Ejercicio Pon color por especie a la gráfica anterior:
Ejercicio Repite la gráfica anterior pero para que se vea así:
Podemos repetir la figura anterior pero cambiando los labels para que digan "Ancho de sépalo" y "Largo de sépalo", respectivamente. Así:
# gráfico base
p <- ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width,
color=Species)) +
geom_point() +
facet_grid(Species ~ .)
# Cambiar texto de los ejes:
p + ylab("Ancho del sépalo") + xlab("Largo del sépalo")
También podemos agregar el resultado de un modelo matemático, como una regresión lineal:
ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width, color=Species)) +
geom_point() +
facet_grid(Species ~ .) +
geom_smooth(method="lm")
## `geom_smooth()` using formula 'y ~ x'
En este tipo de gráficas la altura de las barras puede significar dos cosas:
geom_bar utiliza stat="bin" para variables continuas y stat="count" para variables categóricas.stat="identity" en los argumentos de geom_bar.Ejemplo con los datos de maíces que descargamos de: Arteaga, María Clara et al. (2015), Data from: Genomic variation in recently collected maize landraces from Mexico, Dryad, Dataset, https://doi.org/10.5061/dryad.4t20n
# leer datos asumiendo que están en tu WD
maices<-read.delim("maizteocintle_SNP50k_meta_extended.txt")
Gráfica de número de muestras por estado. Es decir que "cuente" cuantas muestras hay en cada estado y que esa sea la altura de la barra:
p.estados <- ggplot(data = maices,# utiliza los datos maíces
aes(x=Estado)) + # que los estados sean las barras
geom_bar(stat="count") # que la altura de las barras sea "la cuenta" de las veces que aparece cada estado en las muestras
p.estados # ver gráfica
# poner los nombres de los estados en vertical para que se lea mejor
p.estados + theme(axis.text.x = element_text(angle = 90))
Siguiendo con los mismos datos anteriores:
# plot
# utiliza los datos maices
p.altitud <- ggplot(data=maices,
# en X las categorías de altitud (bajo, medio, alto)
# en Y la altitud de las muestras en cada categoría
aes(x=Categ.Altitud, y=Altitud)) +
# queremos un boxplot
geom_boxplot()
p.altitud
Podemos agregar puntos sobre los boxplots para visualizar mejor cuántos datos hay en cada categoría:
p.altitud + geom_jitter()
Al igual que en base, en ggplot es posible cambiar los colores manualmente o cambiando la paleta.
Recomiendo buscar más información y ejemplos en esta excelente guía Cookbook-R colores en ggplot2.
Ejemplos:
Cambiar colores manualmente
# mismo boxplot de hace rato
ggplot(data=maices,
aes(x=Categ.Altitud, y=Altitud,
fill=Categ.Altitud)) + # especificamos que el relleno de los boxplots será por Categ.Altitud
geom_boxplot() +
scale_fill_manual(values=c("red", "blue", "green")) # decimos qué colores queremos manualmente
Cambiar la paleta
# Crear paleta apta para daltónicos:
cbPalette <- c("#999999", "#E69F00", "#56B4E9", "#009E73")
# Usar paleta en gráfica:
ggplot(data=maices,
aes(x=Categ.Altitud, y=Altitud,
fill=Categ.Altitud)) + # especificamos que el relleno de los boxplots será por Categ.Altitud
geom_boxplot() +
scale_fill_manual(values=cbPalette) # le damos la paleta
Usar una paleta de ColorBrewer
ggplot(data=maices,
aes(x=Categ.Altitud, y=Altitud,
fill=Categ.Altitud)) + # especificamos que el relleno de los boxplots será por Categ.Altitud
geom_boxplot() +
scale_fill_brewer(palette="Set1") # tomamos una paleta predefinida de las que vienen con ggplot2
Utilizar gradientes de colores
Primero hagamos una gráfica que se preste a un gradiente de colores:
# Graficar altitud vs latitud
ggplot(maices, aes(x=Latitud, y=Altitud,
colour=Altitud)) + # especificiar que el color será por altitud
geom_point()
Ahora cambiemos el gradiente:
# misma gráfica de arriba
ggplot(maices, aes(x=Latitud, y=Altitud,
colour=Altitud)) +
geom_point() +
# pero cambiando el color
scale_colour_gradientn(colours=terrain.colors(6)) # terrain.colors es una de las paletas predefindas de ggplot2, puedes buscar más googleando
En tus presentaciones, artículos y tesis por favor asegúrate de que todo el texto de tu figura se vea bien. Como tip, cuando la pegues en un documento de texto, la letra más chica no debe ser menor al texto que escribas en tamaño de fuente 8 ó 10 (preferentemente 10) justo debajo de la figura.
En ggplot2 puedes especificar el tamaño de cada elemento de texto (título, leyenda, ejes...) o simplemente agrandarlo todo de un jalón. Ejemplos:
Agrandar todo el texto:
# misma gráfica de arriba
p<-ggplot(maices, aes(x=Latitud, y=Altitud,
colour=Altitud)) + geom_point()
p
# agrandar TODO el texto
p + theme(text=element_text(size=20))
O agrandar solo un texto se interés, por ejemplo el títulod de los ejes:
p + theme(axis.title=element_text(size=20))
Ejercicio: busca cómo se llaman los demás elementos de texto, por ejemplo el texto de los ejes (los numeritos en este caso)
Veamos este ejemplo de R Cookbook sobre mutlipltos:
Primero generamos y guardamos en objetos 4 gráficas:
# This example uses the ChickWeight dataset, which comes with ggplot2
# First plot
p1 <- ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet, group=Chick)) +
geom_line() +
ggtitle("Growth curve for individual chicks")
# Second plot
p2 <- ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet)) +
geom_point(alpha=.3) +
geom_smooth(alpha=.2, size=1) +
ggtitle("Fitted growth curve per diet")
# Third plot
p3 <- ggplot(subset(ChickWeight, Time==21), aes(x=weight, colour=Diet)) +
geom_density() +
ggtitle("Final weight, by diet")
# Fourth plot
p4 <- ggplot(subset(ChickWeight, Time==21), aes(x=weight, fill=Diet)) +
geom_histogram(colour="black", binwidth=50) +
facet_grid(Diet ~ .) +
ggtitle("Final weight, by diet") +
theme(legend.position="none") # No legend (redundant in this graph)
Luego las graficamos juntas con la función multiplot, del paquete Rmisc (que es la misma que viene en link de arriba y que tmb puedes copiar y pegar en tu script):
`
library(Rmisc)
## Loading required package: lattice
## Loading required package: plyr
## Warning: package 'plyr' was built under R version 3.5.2
multiplot(p1, p2, p3, p4, cols=2)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
png(), jpg(), pdf() según el formato en que queramos guardar.dev.offNota para que esto funcione dentro de un chunck de código, tienes que correr las 3 líneas juntas (seleccionadas) en vez de una por una.
png("borrame.png")
multiplot(p1, p2, p3, p4, cols=2)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
dev.off()
## quartz_off_screen
## 2
Si incluyes esto cuando corras tu script remotamente (eg en un cluster) o cuanlo "tejas" aun html, las gráficas se guardarán con los nombres que les digas y en el directorio que especifiques :)
En R studio darle "Export" o "Copy" en el panel de la imagen y seleccionar un nombre de archivo y demás características.
En ggplot2 puedes usar la función ggsave() para guardar uno de tus plots. Por default se guarda el último que corriste:
ggplot(maices, aes(x=Latitud, y=Altitud,
colour=Altitud)) + geom_point()
ggsave(filename = "borrame2.png")
## Saving 7 x 5 in image
También puedes especificar otro plot y ajustar tamaño y resolución (últil porque algunas revistas te van a pedir los plots en pdf y 300 dpi...)
# definir que queremos el plot de uno que guardamos en el objeto p.altitud por ahí arriba
ggsave(plot=p.altitud, file="borrame3.png",
width = 15, height=12, units="cm",
dpi=300)